/*
 * Reviewer.java
 * Author: Sanjeev Kamboj
 */
package superConference;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

/**
 * Reviewer class - Creates a Reviewer object
 * 
 * @author Sanjeev Kamboj
 * @updated 11/26/2013
 */
public class Reviewer extends AbstractUser{
	
	/**
	 * A list of papers that this reviewer has to review.
	 */
	protected List<Paper> my_papers;
	
	/**
	 * A list of reviews for each paper.
	 */
	protected List<Review> my_reviews;
	
	/**
	 * A Map that links paper id to reviews
	 */
	protected Map<Integer, Review> my_paperIdtorev;
	
	/**
	 * A currently selected review
	 */
	protected Review my_chosen_review;
	
	
	/**
	 * Constructs a Reviewer Object
	 * 
	 * @param the_papers A list of papers the reviewer needs to review.
	 * @param the_userID The userId of this reviewer.
	 * @param the_email The email of this reviewer.
	 * @param the_name The_name of this reviewer.
	 * @throws IOException 
	 */
	public Reviewer(final List<Paper> the_papers,
	        		final int the_userID, final String the_email, 
	        		final String the_name) {
		super(the_userID, the_email, the_name);
		
		my_papers = the_papers;
		my_reviews = new ArrayList<Review>();
		my_paperIdtorev = new HashMap<Integer, Review>();
		
		fillMap();  //fill the map

    }
	
	
	/**
	 * Constructs a Reviewer Object without the need for a list
	 * 
	 * @param the_userID The id of the Reviewer
	 * @param the_email The email of the Reviewer
	 * @param the_name The name of the Reviewer
	 */
	public Reviewer(final int the_userID, final String the_email,
			        final String the_name) {
		this(new ArrayList<Paper>(), the_userID, the_email, the_name);
		
	}
	
	
	/**
	 * private method for linking a paper_id to its review
	 */
	private void fillMap() {
		
		for(Paper p : my_papers) {
			addPaper(p);
		}
	}
	
	
	/**
	 * A paper is added to be reviewed by this reviewer.
	 * 
	 * @param the_paper The paper that needs to be reviewed
	 */
	protected void addPaper(final Paper the_paper) {
		
		// The review file names are "ReviewID#.txt" depending on how many
		// papers each reviewer has to review. # is a number so if a reviewer
		//had 3 papers for UserID = 23, path name would be Review231.txt, Review232.txt, etc..
		final Review r = new Review(userID, the_paper.getId(), "Review" + userID + (my_reviews.size() + 1) + ".txt");
		
		
		final File f = the_paper.getFile();
	
		try {
			f.createNewFile();
		} catch (IOException e) {
			System.err.println("File Not Found!");
			e.printStackTrace();
		}
		
		if(!my_papers.contains(the_paper)) {
			my_papers.add(the_paper);
		}
		
		my_reviews.add(r);  
		my_paperIdtorev.put(the_paper.getId(), r);
	}
	
	/**
	 * Private method to retrieve the paper
	 * @param the_paper_id The id of the paper to retrieve
	 * @return The paper whose id is given.
	 */
	public Paper getPaperFromID(final int the_paper_id) {
		//get paper from id and attach review to paper
		Paper temp = null;
		
		for(Paper p : my_papers) {
			if(p.getId() == the_paper_id) {
				temp = p;
			}
		}
		return temp;
	}
	
	/**
	 * Writes the text passed in to a .txt file
	 * 
	 * @param the_paper_id The id of a paper
	 * @param text A text representing what to write to file
	 * @throws FileNotFoundException 
	 */
	//The String text can be changed to a File object
	public void editReview(final int the_paper_id, String text) throws FileNotFoundException {
		
		final Review review = my_paperIdtorev.get(the_paper_id);  //gets review for paper
		
		final PrintWriter out = new PrintWriter(review.getFileName());
		out.println(text); //write contents to text file
		
		
		out.close();
		
	}
	
	
	/**
	 *Gives a File object of the review that is associated with the paper. 
	 * 
	 * @param the_paper_id The id of the paper whose review is needed
	 * @return A file object for the review of this paper
	 */
	public File getReviewFile(final int the_paper_id) {
		
		final Review r = getReview(the_paper_id);
		return new File(r.getFileName());
		
	}
	
	
	/**
	 * Returns the review associated with the paper
	 * 
	 * @param the_paper_id The id of the paper whose Review is needed
	 * @return A review object that is associated with the paper
	 */
	public Review getReview(final int the_paper_id) {
		 //stores which paper to work on
		
		final Review r = my_paperIdtorev.get(the_paper_id);
		my_chosen_review = r;
		return r;
	}
	
	
	//can pass in paper instead
	//Do we need to write to .txt again or is editReview called??
	/**
	 * Submits a review
	 * 
	 * @param the_paper_id The id of the paper whose review needs to be submitted
	 * @param the_f The file that where the review can be found.
	 * @return A boolean for if the paper was found and review is attached
	 * @throws FileNotFoundException 
	 */
	public boolean submitReview(final int the_paper_id, final File the_f) throws FileNotFoundException {
		boolean has_id = false;
		
		if(my_paperIdtorev.containsKey(the_paper_id)) {
			final Review r = my_paperIdtorev.get(the_paper_id);
			r.setSubmission();
			
			//get paper from id and attach review to paper
			//Paper chosen_paper = getPaperFromID(the_paper_id);
			Paper chosen_paper = Paper.getPaperByID(the_paper_id);
			
			r.setFileName(the_f.getName());
			has_id = true;
			chosen_paper.addReview(r);  
		}
		return has_id;
	}
	
	
	/**
	 * Gives the data in the review that is associated with the given paper
	 * 
	 * @param the_paper_id The paper id for whose review is needed.
	 * @return A string representation of everything in the review file.
	 * @throws FileNotFoundException  
	 */
	public String viewReview(final File f) throws FileNotFoundException {
		//final File get_review_file = getReviewFile(the_paper_id);  //gives the review file
															        //associated with the paper
		
		final Scanner scanner = new Scanner(f);
		final StringBuilder sb = new StringBuilder();

		while (scanner.hasNextLine()) {
			sb.append(scanner.nextLine() + "\n");
		}
		scanner.close();
		
		return sb.toString();
	}
	
	/**
	 * Method gives all the Reviews that this Reviewer has
	 * @return A list of Reviews.
	 */
	protected List<Review> getReviews() {
		return my_reviews;
	}
	
	/**
	 * Loads reviews back to its associated paper
	 * @param r The review to load into the data structures
	 */

	protected void updateReview(final Review r, final Paper p) {
	
		my_papers.add(p);
		my_reviews.add(r);
		my_paperIdtorev.put(p.getId(), r);
	
	}
	
			
}
